
#include <iostream>
#include <string>
#include <memory>
#include <unistd.h>
#include <cstdlib>
#include <ctime>
#include "socket.hpp"
#include "Protocal.hpp"
#include "Log.hpp"
using std::cout;
using std::endl;
using namespace socket_ns;
using namespace protocol_ns;

void Usage(const char *arg)
{
    cout << "USAGE:" << endl;
    cout << "#         please enter:  " << arg << "serverip serverport" << endl;
}

class ReqFactory
{
public:
    ReqFactory()
    {
        theoper = "+-*/%&^";
        srand(time(nullptr));
    }
    Request makeit()
    {
        Request req;
        req._x = rand() % 10;
        usleep(111);
        req._y = rand() % 5;
        usleep(333);
        req._oper = theoper[rand() % theoper.size()];
        return req;
    }

private:
    std::string theoper;
};

// ./client 127.0.0.1 8888
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
        exit(1);
    }
    uint16_t serverport = std::stoi(argv[2]);
    std::string serverip(argv[1]);
    InetAddr serveraddr(serverip, serverport);
    ReqFactory fac;
    std::unique_ptr<Socket> uptr = std::make_unique<TcpSocket>();
    bool ret = uptr->BuildConnectSocket(serveraddr);
    if (!ret)
        exit(2);
    int n = 5;
    while (n--)
    {
        sleep(1);
        Request req = fac.makeit();
        std::string message;
        req.Serialize(&message);
        // cout << "message:\n"
        //      << message << endl;
        message = Encode(message);
        cout << "message Encode:\n"
             << message << endl;
        uptr->Send(message);
    }
    cout << "---------------------------------" << endl;
    while (true)
    {
        std::string ret;
        uptr->Recv(&ret);
        std::string tmp = Decode(ret);
        while (!tmp.empty())
        {
            // cout << "whole ret json:\n"
            //      << tmp << endl;
            Response res;
            res.DeSerialize(tmp);
            cout << "result is:\n"
                 << res._result << "[" << res._code << "]" << endl;
            tmp = Decode(ret);
        }
    }
    // while (true)
    // {
    //     sleep(1);
    //     Request req=fac.makeit();
    //     std::string message;
    //     req.Serialize(&message);
    //     cout<<"message:\n"<<message<<endl;
    //     message=Encode(message);
    //     cout<<"message Encode:\n"<<message<<endl;
    //     uptr->Send(message);
    //     std::string ret;
    //     uptr->Recv(&ret);
    //     std::string tmp=Decode(ret);
    //     cout<<"whole ret json:\n"<<tmp<<endl;
    //     Response res;
    //     res.DeSerialize(tmp);
    //     cout<<"result is:\n"<<res._result<<"["<<res._code<<"]"<<endl;

    // }

    return 0;
}
// int main()
// {
//     Enablescreen();
//     // TcpSocket client;
//     UdpSocket client;
//     InetAddr server("127.0.0.1", 8888);
//     struct sockaddr_in tmp=server.Addr();
//     socklen_t len=sizeof(tmp);
//     client.BuildUdpClientSocket();

//     int sockfd = client.returnfd();
//     while (true)
//     {
//         cout << "please enter#";
//         std::string what;
//         std::getline(std::cin, what);
//         sendto(sockfd, what.c_str(), what.size(), 0,(struct sockaddr*)&tmp,len);
//         char buffer[1024];
//         int num = recv(sockfd, buffer, sizeof(buffer), 0);
//         if (num > 0)
//         {
//             buffer[num] = 0;
//             cout << buffer << endl;
//         }
//         else if (num < 0)
//         {
//             cout << "recv error" << endl;
//             continue;
//         }
//     }

//     return 0;
// }